﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Drawing;
using Clandestine.Base;

namespace Clandestine.Graphics.Animation
{
	public partial class AnimatedSprite
	{
		private Dictionary<string, Animation> Animations = new Dictionary<string, Animation>();

		public void AddAnimations(string spritesheet, SpritesheetSelection[] animations)
		{
			Bitmap bmp = new Bitmap(spritesheet);
			foreach (SpritesheetSelection s in animations)
			{
				Animation a = new Animation(base.Graphics, s.Name, s.Interval, s.Loop, spritesheet, bmp, GridWidth, GridHeight, s.RowStart, s.ColStart, s.RowEnd, s.ColEnd);
				if (s.Interval > 0)
					a.Interval = s.Interval;
				this.AddAnimation(s.Name, a);
			}
		}

		public void AddAnimations(string spritesheet, string metadata)
		{
			DateTime timeStart = DateTime.Now;
			XmlTextReader xml = new XmlTextReader(metadata);
			Bitmap bmp = new Bitmap(spritesheet);

			// Read that sexy metadata
			while (xml.Read())
			{
				// General stuff
				if ((xml.NodeType == XmlNodeType.Element) && (xml.Name == "animations"))
				{
					GridWidth = int.Parse(xml.GetAttribute("gridWidth"));
					GridHeight = int.Parse(xml.GetAttribute("gridHeight"));
				}

				// Animation
				if ((xml.NodeType == XmlNodeType.Element) && (xml.Name == "animation"))
				{
					string name = xml.GetAttribute("name");
					double interval = double.Parse(xml.GetAttribute("interval")); // I bet these throw exceptions one day. Have fun!
					bool loop = bool.Parse(xml.GetAttribute("loop"));
					Animation a = new Animation(base.Graphics, name, interval, loop);

					// Add those frames!
					while (!((xml.NodeType == XmlNodeType.EndElement) && (xml.Name == "animation")) && xml.Read())
						if ((xml.NodeType == XmlNodeType.Element) && (xml.Name == "frames"))
						{
							int rowStart = int.Parse(xml.GetAttribute("rowStart"));
							int colStart = int.Parse(xml.GetAttribute("colStart"));
							int rowEnd = int.Parse(xml.GetAttribute("rowEnd"));
							int colEnd = int.Parse(xml.GetAttribute("colEnd"));
							a.AddFrames(spritesheet, bmp, GridWidth, GridHeight, rowStart, colStart, rowEnd, colEnd);
						}

					this.AddAnimation(a.Name, a);
				}
			}
			xml.Close();

			Log.i("Animation: Loading spritesheet, \"{0}\", took {1}ms", spritesheet, (DateTime.Now - timeStart).Milliseconds);
		}

		private void AddAnimation(string name, Animation animation)
		{
			if (!Animations.ContainsKey(name))
			{
				Animations.Add(name, animation);
				//if (animation.Name != string.Empty)
				//    Log.w("Animation: We are renaming animation, \"{0}\" to \"{1}\", this could cause problems in whatever AnimatedSprite it is currently a member of.", animation.Name, name);
				animation.Name = name;
				if (CurrentAnimation == null)
					SetAnimation(name);
			}
			else
				Log.w("Animation: Cannot add animation, \"{0}\", to animated sprite as an animation with that name already exists.", name);
		}

		public void RemoveAnimation(string name)
		{
			if (Animations.ContainsKey(name))
				Animations.Remove(name);
			else
				Log.w("Animation: tried to delete animation, \"{0}\", from an animated sprite but no animation with that name existed.", name);
		}

		public void ClearAnimations()
		{
			Animations.Clear();
			Log.i("Animation: Clearing an animated sprite..."); // This could be more useful if the class had a .Name
		}

		public void SetAnimation(string name)
		{
			if (Animations.ContainsKey(name))
			{
				bool playing = false;
				if (CurrentAnimation != null) // may be first animation
				{
					playing = CurrentAnimation.Playing;
					CurrentAnimation.Playing = false; // Disable it's tmr!
				}
				CurrentAnimation = Animations[name];
				CurrentAnimation.Playing = playing;
			}
			else
				Log.w("Animation: Tried to set animation to, \"{0}\", but no such animation exists in here.", name);
		}
        

	}
}
